#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include "driver/gpio.h"
#include <string.h>
#include "driver/uart.h"

// 程序功能：初始化串口并且发送数据，同时时刻读串口，并将接收到的数据返回
//      1.先初始化LED和UART
//      2.创建两个任务，一个led，一个UART
//      3.c语言中：'\0'  是字符串的结束符

#define io_led1 12
#define io_led2 13
static const char *TAG = "UART TEST";

TaskHandle_t LED_Handle;
void LED_task(void *xTask);
TaskHandle_t UART_Handle;
void UART_task(void *xTask);

void configure_led(void)
{
    gpio_config_t io_config = {
        .pin_bit_mask = (1ull << io_led1) | (1ull << io_led2),
        .mode = GPIO_MODE_OUTPUT,
        .pull_down_en = 1};
    gpio_config(&io_config);
}
void configure_uart(void)
{
    //-1.配置串口结构体
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_APB};
    ESP_ERROR_CHECK(uart_param_config(UART_NUM_0, &uart_config));
    // uart_config(115200,UART_SCLK_DEFAULT);//默认配置串口1

    //-2.设置串口引脚，无引脚绑定使用UART_PIN_NO_CHANGE
    ESP_ERROR_CHECK(uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));

    //-3.设置串口buffer，并且驱动串口开始
    const int uart_buffer_size = (1024 * 2);
    QueueHandle_t uart_queue; // Setup UART buffered IO with event queue
    // Install UART driver using an event queue here
    ESP_ERROR_CHECK(uart_driver_install(UART_NUM_0, uart_buffer_size, uart_buffer_size, 10, &uart_queue, 0));
}


void app_main(void)
{
    //-系统初始化
    configure_led();
    configure_uart();

    vTaskSuspendAll();
    xTaskCreatePinnedToCore(LED_task, "LED_task", 1024 * 3, NULL, 3, &LED_Handle, 1);
    xTaskCreatePinnedToCore(UART_task, "UART_task", 1024 * 3, NULL, 2, &UART_Handle, 1);
    xTaskResumeAll();
}


void LED_task(void *xTask)
{
    while (1)
    {
        gpio_set_level(io_led1, 1);
        gpio_set_level(io_led2, 0);
        vTaskDelay(300 / portTICK_PERIOD_MS);

        gpio_set_level(io_led1, 0);
        gpio_set_level(io_led2, 1);
        vTaskDelay(300 / portTICK_PERIOD_MS);
    }
}
void UART_task(void *xTask)
{
    //-串口写数据，需要传入地址以及字节长度
    char *test_str = "This is a test string.\n";
    uart_write_bytes(UART_NUM_0, (const char *)test_str, strlen(test_str)); //! 需要加上#include <string.h>库文件
    while (1)
    {

        // Configure a temporary buffer for the incoming data
        uint8_t *data = (uint8_t *)malloc(1024);

        while (1)
        {
            // Read data from the UART
            int len = uart_read_bytes(UART_NUM_0, data, 1023, 20 / portTICK_PERIOD_MS);
            // Write data back to the UART
            uart_write_bytes(UART_NUM_0, (const char *)data, len);
            if (len)
            {
                data[len] = '\0';//字符串的结束符
                ESP_LOGI(TAG, "Recv str: %s", (char *)data);
            }
        }
    }
}
